package hu.ngms.jpf.maven;

public class Threading {
	
	private Integer resource1 = new Integer(1);
	private Integer resource2 = new Integer(2);
	
	public void deadlock() {
		DeadlockThread1 t1 = new DeadlockThread1();
		DeadlockThread2 t2 = new DeadlockThread2();
		
		new Thread(t1).start();
		new Thread(t2).start();
	}
	
	public void race() {
		RaceThread1 t1 = new RaceThread1();
		RaceThread2 t2 = new RaceThread2();

		new Thread(t1).start();
		new Thread(t2).start();
	}
	
	public static void main(String[] args) {
		new Threading().deadlock();
	}
	
	private class DeadlockThread1 implements Runnable {

		@Override
		public void run() {
			while (true) {
				synchronized (resource1) {
					System.out.println("T1: lock resource1");
					synchronized (resource2) {
						System.out.println("T1: lock resource2");
					}
				}
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
	
	private class DeadlockThread2 implements Runnable {

		@Override
		public void run() {
			while (true) {
				synchronized (resource2) {
					System.out.println("T2: lock resource2");
					synchronized (resource1) {
						System.out.println("T2: lock resource1");
					}
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
	
	private class RaceThread1 implements Runnable {

		@Override
		public void run() {
			resource1++;
			resource2 = Integer.MAX_VALUE - resource1;
		}
		
	}
	
	private class RaceThread2 implements Runnable {

		@Override
		public void run() {
			resource2++;
			resource1 = Integer.MAX_VALUE - resource2;
		}
		
	}

}
